﻿using LxBasic;
using System;
using System.Windows.Media.Media3D;

namespace LxCFD
{
    public struct PlaneArrowFactory
    {
        public PlaneArrowFactory()
        {
            Positions = new Point3D[5];
            TriangleIndices = new int[6];
            int[] ts = TriangleIndices;
            //添加三角形
            ts[0] = 0;
            ts[1] = 1;
            ts[2] = 2;
            ts[3] = 0;
            ts[4] = 3;
            ts[5] = 4;
        }
        public Point3D[] Positions;
        public int[] TriangleIndices;
        public void CreateArrow(Point3D basepoint, Vector3D axis,  double tailRProportion = 0.08)
        {
            Point3D[] ps = Positions;
            ps[0] = basepoint + axis;    
            (Vector3D u, Vector3D v) = FindVerticalVector(axis);
            double tailRadius = tailRProportion * axis.Length;
            u *= tailRadius;
            v *= tailRadius;
            ps[1] = basepoint + u;
            ps[2] = basepoint - u;
            ps[3] = basepoint + v;
            ps[4] = basepoint - v;    
        }
        private (Vector3D u, Vector3D v) FindVerticalVector(Vector3D vector)
        {
            Vector3D u = (Math.Abs(vector.X) < Math.Abs(vector.Y)) ?
                new Vector3D(0, vector.Z, -vector.Y) :
                new Vector3D(vector.Z, 0, -vector.X);
            u.Normalize();
            Vector3D v = Vector3D.CrossProduct(vector, u);
            v.Normalize();
            return (u, v);
        }
    }
    public struct PlaneArrowFactoryOld
    {
        public PlaneArrowFactoryOld()
        {
            Positions = new Point3D[9];
            TriangleIndices = new int[12];
            int[] ts = TriangleIndices;
            //添加三角形
            ts[0] = 0;
            ts[1] = 1;
            ts[2] = 8;
            ts[3] = 2;
            ts[4] = 3;
            ts[5] = 8;
            ts[6] = 4;
            ts[7] = 5;
            ts[8] = 8;
            ts[9] = 6;
            ts[10] = 7;
            ts[11] = 8;
        }
        public Point3D[] Positions;
        public int[] TriangleIndices;
        public bool CreateArrow(Point3D basepoint, Vector3D axis, double headProportion = 0.5, double tailRProportion = 0.05, double headRProportion = 0.1)
        {
            double len = axis.Length;
            if (len == 0) return false;

            Point3D[] ps = Positions;
            Point3D tailPoint = basepoint + (1 - headProportion) * axis;
            (Vector3D u, Vector3D v) = FindVerticalVector(axis);
            double tailRadius = tailRProportion * len;
            Vector3D u1 = tailRadius * u;
            Vector3D v1 = tailRadius * v;
            double headRadius = headRProportion * len;
            Vector3D u2 = headRadius * v;
            Vector3D v2 = headRadius * v;
            ps[0] = basepoint + u1;
            ps[1] = basepoint - u1;
            ps[2] = tailPoint + u2;
            ps[3] = tailPoint - u2;
            ps[4] = basepoint + v1;
            ps[5] = basepoint - v1;
            ps[6] = tailPoint + v2;
            ps[7] = tailPoint - v2;
            ps[8] = basepoint + axis;

            return true;
        }
        private (Vector3D u, Vector3D v) FindVerticalVector(Vector3D vector)
        {
            Vector3D u = (Math.Abs(vector.X) < Math.Abs(vector.Y)) ?
                new Vector3D(0, vector.Z, -vector.Y) :
                new Vector3D(vector.Z, 0, -vector.X);
            u.Normalize();
            Vector3D v = Vector3D.CrossProduct(vector, u);
            v.Normalize();
            return (u, v);
        }
    }
}